﻿//-------------------------------------
// WBFSSync - WBFSSync.exe
//
// Copyright 2009 Caian (ÔmΣga Frøst) <frost.omega@hotmail.com> :
//
// WBFSSync is Licensed under the terms of the Microsoft Reciprocal License (Ms-RL)
//
// ExplorerListView.cs:
//
// Customiza orna a ListView para o estilo do Explorer
//
//-------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;

namespace WBFSSync.AeroControls
{
    public enum ViewMode : byte
    {
        Unknown,
        Details,
        Tile,
        Cover,
        List,
    }

    public class ExplorerListView : ListView
    {
        //------------------ Classes / Estruturas úteis

        class ListViewItemComparer : IComparer
        {
            ExplorerListView parent = null;

            public ListViewItemComparer(ExplorerListView p)
            {
                parent = p;
            }

            public int Compare(object x, object y)
            {
                string a = "";
                string b = "";
                int column = parent.SortingColumn;

                ListViewItem ix = (ListViewItem)x;
                ListViewItem iy = (ListViewItem)y;

                if (ix.SubItems.Count > column)
                {
                    if ((column == 0) && (((TagMetadata)ix.Tag).Type == SelectionType.Drive))
                    {
                        a = ix.Name;
                    }
                    else
                    {
                        a = ix.SubItems[column].Text;
                    }
                }

                if (iy.SubItems.Count > column)
                {
                    if ((column == 0) && (((TagMetadata)iy.Tag).Type == SelectionType.Drive))
                    {
                        b = iy.Name;
                    }
                    else
                    {
                        b = iy.SubItems[column].Text;
                    }
                }

                if (parent.Sorting == SortOrder.Ascending)
                    return String.Compare(a, b);
                else
                    return String.Compare(b, a);
            }
        }

        //------------------ Variáveis

        bool suspendCoverMode = false;
        public Boolean SuspendCoverMode
        { 
            get 
            { 
                return suspendCoverMode; 
            } 
            set 
            { 
                suspendCoverMode = value; 
                OnSuspendCoverModeChanged();
            } 
        }

        ViewMode viewMode = ViewMode.Tile;
        public ViewMode ViewMode 
        { 
            get 
            { 
                return viewMode; 
            } 
            set 
            { 
                viewMode = value; 
                OnViewModeChanged();
            } 
        }
        public event EventHandler ViewModeChanged;

        Size tileSize_tilemode = new Size(250, 60);
        public Size TileModeTileSize
        {
            get
            {
                return tileSize_tilemode;
            }
        }

        Size tileSize_covermode = new Size(250, 80);
        public Size CoverModeTileSize
        {
            get
            {
                return tileSize_covermode;
            }
        }

        Size tileSize_fullsizemode = new Size(200, 250);
        public Size FullSizeModeTileSize
        {
            get
            {
                return tileSize_fullsizemode;
            }
        }

        bool forceFullSize = false;
        public Boolean ForceFullSize
        {
            get
            {
                return forceFullSize;
            }

            set
            {
                forceFullSize = value;
                OnForceFullSize();
            }
        }

        bool drawCoverShadow = false;
        public Boolean DrawCoverShadow { get { return drawCoverShadow; } set { drawCoverShadow = value; Invalidate(); } }

        ListViewItemComparer comparer = null;
        int sortingColumn = 0;
        public int SortingColumn { get { return sortingColumn; } set { sortingColumn = value; Sort(); } }

        SolidBrush GrayBrush = new SolidBrush(Color.FromArgb(109, 109, 109));
        
        Point mousePosition = new Point(-1, -1);
        int itemUnderMouse = -1;

        //------------------ Rotinas

        public ExplorerListView() : base()
        {
            DoubleBuffered = true;
            OwnerDraw = true;
            comparer = new ListViewItemComparer(this);
            ListViewItemSorter = comparer;

            SmallImageList = new ImageList();
            SmallImageList.ImageSize = new Size(20, 20); //Força a altura dos itens no modo Detalhes e Lista
        }

        public bool CheckMouseIntersection(Rectangle rect)
        {
            return ((mousePosition.X >= rect.X) && (mousePosition.X < rect.Right) &&
                    (mousePosition.Y >= rect.Y) && (mousePosition.Y < rect.Bottom));
        }

        public bool CheckMouseIntersection2(Rectangle rect)
        {
            Point mouse = PointToClient(MousePosition);
            return ((mouse.X >= rect.X) && (mouse.X < rect.Right) &&
                    (mouse.Y >= rect.Y) && (mouse.Y < rect.Bottom));
        }

        //------------------ Overrides

        protected override void OnDrawItem(DrawListViewItemEventArgs e)
        {
            e.Graphics.SmoothingMode = SmoothingMode.HighSpeed;
            e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
            e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

            bool mouseover = (e.ItemIndex == itemUnderMouse);

            if (forceFullSize)
            {
                DrawFullSizeCoverItem(e, mouseover);
            }
            else
            {
                switch (viewMode)
                {
                    case ViewMode.Cover:
                        DrawTileBackground(e, mouseover);

                        if (suspendCoverMode) DrawTileItem(e, mouseover);
                        else DrawCoverItem(e, mouseover);

                        break;

                    case ViewMode.Tile:
                        DrawTileBackground(e, mouseover);
                        DrawTileItem(e, mouseover);
                        break;

                    case ViewMode.List:
                        DrawListItem(e, mouseover);
                        break;
                }
            }

            base.OnDrawItem(e);
        }

        protected override void OnDrawSubItem(DrawListViewSubItemEventArgs e)
        {
            e.Graphics.SmoothingMode = SmoothingMode.HighSpeed;
            e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
            e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

            bool mouseover = (e.ItemIndex == itemUnderMouse);

            DrawDetailsSubItem(e, mouseover);
            base.OnDrawSubItem(e);
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            mousePosition = new Point(-1, -1);
            itemUnderMouse = -1;
            Invalidate();
            base.OnMouseLeave(e);
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            mousePosition = new Point(e.X, e.Y);

            int lastItemUnderMouse = itemUnderMouse;
            itemUnderMouse = -1;
            for (int i = 0; i < Items.Count; i++)
            {
                if (CheckMouseIntersection(Items[i].Bounds))
                {
                    itemUnderMouse = i;
                    Invalidate(Items[i].Bounds);
                    break;
                }
            }
            if (lastItemUnderMouse >= Items.Count) lastItemUnderMouse = -1;
            if (lastItemUnderMouse >= 0) 
                Invalidate(Items[lastItemUnderMouse].Bounds);

        }

        //------------------ Desenho

        private void DrawTileItem(DrawListViewItemEventArgs e, bool mouseover)
        {
            int icon_x = e.Bounds.Left + 4;
            int icon_y = e.Bounds.Top + (e.Bounds.Height - 48) / 2;

            String[] subitemstext = null;

            //Extrai informação do item
            TagMetadata metadata = (TagMetadata)e.Item.Tag;
            Image image = GetTileIconFromMetadata(metadata);
            if (image != null) e.Graphics.DrawImage(image, icon_x, icon_y, 48, 48);

            
            if (metadata.Type == SelectionType.Disc)
            {
                subitemstext = new string[3];
                subitemstext[0] = e.Item.SubItems[1].Text + " - " + e.Item.SubItems[0].Text;
                subitemstext[1] = e.Item.SubItems[2].Text;
                subitemstext[2] = e.Item.SubItems[3].Text;
            }
            else if (metadata.Type == SelectionType.Drive)
            {
                IDrive drive = metadata.Meta1 as IDrive;

                if ((drive.Ready) && (drive.Size > 0))
                {
                    if (drive.FreeSpace == 0) //CD Cheio
                    {
                        subitemstext = new string[2];
                        subitemstext[0] = e.Item.SubItems[0].Text;
                        subitemstext[1] = e.Item.SubItems[3].Text;
                    }
                    else
                    {
                        subitemstext = new string[3];
                        subitemstext[0] = e.Item.SubItems[0].Text;
                        subitemstext[2] = e.Item.SubItems[3].Text;

                        // Desenha a barra de espaço reservado e espaço utilizado...

                        int progress_x = 4 + 48 + 2 + 2;
                        int progress_y = e.Bounds.Top + (e.Bounds.Height - 13) / 2 - 1;

                        int progress_width = e.Bounds.Width - 5 - progress_x;
                        progress_x += e.Bounds.X;

                        e.Graphics.DrawImage(Skin.progresscontainer_l, progress_x, progress_y, 4, 13);
                        e.Graphics.DrawImage(Skin.progresscontainer_m, progress_x + 4, progress_y, progress_width - 8, 13);
                        e.Graphics.DrawImage(Skin.progresscontainer_r, progress_x + progress_width - 4, progress_y, 4, 13);

                        //Espaço reservado

                        if (drive.ReservedSpace > 0)
                        {
                            float usedratio = Math.Min((float)(drive.UsedSpace + drive.ReservedSpace) / (float)drive.Size, 1.0f);
                            int progress_bar_width = (int)(usedratio * (progress_width - 2));

                            e.Graphics.DrawImage(Skin.progressbar_gray, progress_x + 1, progress_y + 1, progress_bar_width, 11);
                        }

                        //Espaço usado

                        if (drive.UsedSpace > 0)
                        {
                            float usedratio = (float)drive.UsedSpace / (float)drive.Size;
                            int progress_bar_width = (int)(usedratio * (progress_width - 2));

                            e.Graphics.DrawImage(usedratio >= 0.9 ? Skin.progressbar_red : Skin.progressbar_blue, progress_x + 1,
                                progress_y + 1, progress_bar_width, 11);
                        }
                    }

                }
                else
                {
                    subitemstext = new string[1];
                    subitemstext[0] = e.Item.SubItems[0].Text;
                }
            }
            //

            if (subitemstext == null)
            {
                subitemstext = new string[e.Item.SubItems.Count];
                for (int i = 0; i < subitemstext.Length; i++)
                {
                    subitemstext[i] = e.Item.SubItems[i].Text;
                }
            }

            int text_x = 4 + 48 + 2; //Sim... 54...
            int text_height = Skin.IconTitleFont.Height - 2;
            float first_line_y = e.Bounds.Top + (e.Bounds.Height - (text_height * subitemstext.Length)) / 2.0f - 3;

            StringFormat format = new StringFormat();
            format.Trimming = StringTrimming.EllipsisCharacter;
            format.LineAlignment = StringAlignment.Near;
            format.Alignment = StringAlignment.Near;

            for (int i = 0; i < subitemstext.Length; i++)
            {
                RectangleF rect = new RectangleF(e.Bounds.Left + text_x, first_line_y + (text_height * i),
                    e.Bounds.Width - text_x, Skin.IconTitleFont.Height);
                e.Graphics.DrawString(subitemstext[i], Skin.IconTitleFont, (i == 0) ? Brushes.Black : GrayBrush, 
                    rect, format);
            }

            subitemstext = null;
        }

        private void DrawCoverItem(DrawListViewItemEventArgs e, bool mouseover)
        {
            int icon_x = e.Bounds.Left + 4;
            int icon_y = e.Bounds.Top + (e.Bounds.Height - 72) / 2;

            //Extrai informação do item
            TagMetadata metadata = (TagMetadata)e.Item.Tag;
            Image image = GetCoverIconFromMetadata(metadata, e.Item.SubItems[1].Text);

            if (metadata.Type == SelectionType.Disc)
            {
                icon_x += 11;

                if (drawCoverShadow)
                {
                    if (Skin.cover_shadow != null) e.Graphics.DrawImage(Skin.cover_shadow, icon_x - 3, icon_y - 3,
                         Skin.cover_shadow.Width, Skin.cover_shadow.Height);
                }
            }

            if (image != null) e.Graphics.DrawImage(image, icon_x, icon_y, image.Width, image.Height);

            //

            int text_x = 4 + 72 + 2; //Sim... 78...
            int text_height = Skin.IconTitleFont.Height + 1;
            float first_line_y = e.Bounds.Top + (e.Bounds.Height - (text_height * e.Item.SubItems.Count)) / 2.0f;

            StringFormat format = new StringFormat();
            format.Trimming = StringTrimming.EllipsisCharacter;
            format.LineAlignment = StringAlignment.Near;
            format.Alignment = StringAlignment.Near;

            for (int i = 0; i < e.Item.SubItems.Count; i++)
            {
                RectangleF rect = new RectangleF(e.Bounds.Left + text_x, first_line_y + (text_height * i),
                    e.Bounds.Width - text_x, text_height);
                e.Graphics.DrawString(e.Item.SubItems[i].Text, Skin.IconTitleFont, (i == 0) ? Brushes.Black : GrayBrush,
                    rect, format);
            }
        }

        private void DrawFullSizeCoverItem(DrawListViewItemEventArgs e, bool mouseover)
        {
            DrawTileBackground(e, mouseover);

            if (drawCoverShadow)
            {
                if (Skin.cover_shadow_big != null) e.Graphics.DrawImage(Skin.cover_shadow_big,
                    e.Bounds.Left - 10 + (e.Bounds.Width - 160) / 2, e.Bounds.Top + 4 - 10, 180, 245);
            }

            Image cover = Covers.GetFullSizeCover(e.Item.Text);
            if (cover != null) e.Graphics.DrawImage(cover, e.Bounds.Left + (e.Bounds.Width - 160) / 2,
                 e.Bounds.Top + 4, 160, 225);

            
            StringFormat format = new StringFormat();
            format.Alignment = StringAlignment.Center;

            RectangleF textpos = new RectangleF(e.Bounds.Left, e.Bounds.Bottom - Skin.IconTitleFont.Height - 2,
                e.Bounds.Width, Skin.IconTitleFont.Height);

            e.Graphics.DrawString(e.Item.Text, Skin.IconTitleFont, Brushes.Black, textpos, format);
        }

        private void DrawDetailsSubItem(DrawListViewSubItemEventArgs e, bool mouseover)
        {
            Boolean first = (e.ColumnIndex == 0);
            Boolean last = (e.ColumnIndex == e.Item.SubItems.Count - 1);

            int textdraw_x = 4;

            if ((Columns.Count == 1)||(e.Item.SubItems.Count == 1)) //Único sub-item
            {
                textdraw_x = 22;

                if ((e.ItemState & ListViewItemStates.Selected) != (ListViewItemStates)0)
                {
                    if (Focused)
                    {
                        e.Graphics.DrawImage(Skin.explorer_detail_selection_l_c, e.Bounds.X, e.Bounds.Y, 3, e.Bounds.Height);
                        e.Graphics.DrawImage(Skin.explorer_detail_selection_m_c, e.Bounds.X + 3, e.Bounds.Y, e.Bounds.Width - 6, e.Bounds.Height);
                        e.Graphics.DrawImage(Skin.explorer_detail_selection_r_c, e.Bounds.Right - 3, e.Bounds.Y, 3, e.Bounds.Height);
                    }
                    else
                    {
                        e.Graphics.DrawImage(Skin.explorer_detail_selection_l_oc, e.Bounds.X, e.Bounds.Y, 3, e.Bounds.Height);
                        e.Graphics.DrawImage(Skin.explorer_detail_selection_m_oc, e.Bounds.X + 3, e.Bounds.Y, e.Bounds.Width - 6, e.Bounds.Height);
                        e.Graphics.DrawImage(Skin.explorer_detail_selection_r_oc, e.Bounds.Right - 3, e.Bounds.Y, 3, e.Bounds.Height);
                    }
                }
                else if (mouseover)
                {
                    e.Graphics.DrawImage(Skin.explorer_detail_selection_l_o, e.Bounds.X, e.Bounds.Y, 3, e.Bounds.Height);
                    e.Graphics.DrawImage(Skin.explorer_detail_selection_m_o, e.Bounds.X + 3, e.Bounds.Y, e.Bounds.Width - 6, e.Bounds.Height);
                    e.Graphics.DrawImage(Skin.explorer_detail_selection_r_o, e.Bounds.Right - 3, e.Bounds.Y, 3, e.Bounds.Height);
                }
            }
            else
            {
                if (first) //Primeiro: borda da esquerda + meio
                {
                    textdraw_x = 22;
                    if ((e.ItemState & ListViewItemStates.Selected) != (ListViewItemStates)0)
                    {
                        if (Focused)
                        {
                            e.Graphics.DrawImage(Skin.explorer_detail_selection_l_c, e.Bounds.X, e.Bounds.Y, 3, e.Bounds.Height);
                            e.Graphics.DrawImage(Skin.explorer_detail_selection_m_c, e.Bounds.X + 3, e.Bounds.Y, e.Bounds.Width - 3, e.Bounds.Height);
                        }
                        else
                        {
                            e.Graphics.DrawImage(Skin.explorer_detail_selection_l_oc, e.Bounds.X, e.Bounds.Y, 3, e.Bounds.Height);
                            e.Graphics.DrawImage(Skin.explorer_detail_selection_m_oc, e.Bounds.X + 3, e.Bounds.Y, e.Bounds.Width - 3, e.Bounds.Height);
                        }
                    }
                    else if (mouseover)
                    {
                        e.Graphics.DrawImage(Skin.explorer_detail_selection_l_o, e.Bounds.X, e.Bounds.Y, 3, e.Bounds.Height);
                        e.Graphics.DrawImage(Skin.explorer_detail_selection_m_o, e.Bounds.X + 3, e.Bounds.Y, e.Bounds.Width - 3, e.Bounds.Height);
                    }
                }
                else if (last) //Último: meio + borda da direita
                {
                    int widthadd = 0;
                    for (int i = e.ColumnIndex + 1; i < Columns.Count; i++) widthadd += Columns[i].Width;

                    if ((e.ItemState & ListViewItemStates.Selected) != (ListViewItemStates)0)
                    {
                        if (Focused)
                        {
                            e.Graphics.DrawImage(Skin.explorer_detail_selection_m_c, e.Bounds.X, e.Bounds.Y, e.Bounds.Width + widthadd - 3, e.Bounds.Height);
                            e.Graphics.DrawImage(Skin.explorer_detail_selection_r_c, e.Bounds.Right + widthadd - 3, e.Bounds.Y, 3, e.Bounds.Height);
                        }
                        else
                        {
                            e.Graphics.DrawImage(Skin.explorer_detail_selection_m_oc, e.Bounds.X, e.Bounds.Y, e.Bounds.Width + widthadd - 3, e.Bounds.Height);
                            e.Graphics.DrawImage(Skin.explorer_detail_selection_r_oc, e.Bounds.Right + widthadd - 3, e.Bounds.Y, 3, e.Bounds.Height);
                        }
                    }
                    else if (mouseover)
                    {
                        e.Graphics.DrawImage(Skin.explorer_detail_selection_m_o, e.Bounds.X, e.Bounds.Y, e.Bounds.Width + widthadd - 3, e.Bounds.Height);
                        e.Graphics.DrawImage(Skin.explorer_detail_selection_r_o, e.Bounds.Right + widthadd - 3, e.Bounds.Y, 3, e.Bounds.Height);
                    }
                }
                else //Meio: meio (lol)
                {
                    if ((e.ItemState & ListViewItemStates.Selected) != (ListViewItemStates)0)
                    {
                        if (Focused)
                        {
                            e.Graphics.DrawImage(Skin.explorer_detail_selection_m_c, e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height);
                        }
                        else
                        {
                            e.Graphics.DrawImage(Skin.explorer_detail_selection_m_oc, e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height);
                        }
                    }
                    else if (mouseover)
                    {
                        e.Graphics.DrawImage(Skin.explorer_detail_selection_m_o, e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height);
                    }
                }
            }

            if (first) //Desenha ícone
            {
                
                //Extrai informação do item
                TagMetadata metadata = (TagMetadata)e.Item.Tag;
                Image image = GetSmallIconFromMetadata(metadata);
                if (image != null) e.Graphics.DrawImage(image, e.Bounds.X + 4, e.Bounds.Y + 2, 16, 16);
            }

            if (e.SubItem.Text != "")
            {
                StringFormat format = new StringFormat();
                format.Trimming = StringTrimming.EllipsisCharacter;
                format.LineAlignment = StringAlignment.Near;
                format.Alignment = StringAlignment.Near;

                RectangleF bounds = new RectangleF(e.Bounds.Left + textdraw_x,
                    e.Bounds.Top + (e.Bounds.Height - Skin.IconTitleFont.Height) / 2, Columns[e.ColumnIndex].Width - 
                    textdraw_x, Skin.IconTitleFont.Height);

                e.Graphics.DrawString(e.SubItem.Text, Skin.IconTitleFont, first ? Brushes.Black : GrayBrush,bounds,
                    format);
            }
        }

        private void DrawListItem(DrawListViewItemEventArgs e, bool mouseover)
        {
            int textdraw_x = 22;

            if ((e.State & ListViewItemStates.Selected) != (ListViewItemStates)0)
            {
                if (Focused)
                {
                    e.Graphics.DrawImage(Skin.explorer_detail_selection_l_c, e.Bounds.X, e.Bounds.Y, 3, e.Bounds.Height);
                    e.Graphics.DrawImage(Skin.explorer_detail_selection_m_c, e.Bounds.X + 3, e.Bounds.Y, e.Bounds.Width - 6, e.Bounds.Height);
                    e.Graphics.DrawImage(Skin.explorer_detail_selection_r_c, e.Bounds.Right - 3, e.Bounds.Y, 3, e.Bounds.Height);
                }
                else
                {
                    e.Graphics.DrawImage(Skin.explorer_detail_selection_l_oc, e.Bounds.X, e.Bounds.Y, 3, e.Bounds.Height);
                    e.Graphics.DrawImage(Skin.explorer_detail_selection_m_oc, e.Bounds.X + 3, e.Bounds.Y, e.Bounds.Width - 6, e.Bounds.Height);
                    e.Graphics.DrawImage(Skin.explorer_detail_selection_r_oc, e.Bounds.Right - 3, e.Bounds.Y, 3, e.Bounds.Height);
                }
            }
            else if (mouseover)
            {
                e.Graphics.DrawImage(Skin.explorer_detail_selection_l_o, e.Bounds.X, e.Bounds.Y, 3, e.Bounds.Height);
                e.Graphics.DrawImage(Skin.explorer_detail_selection_m_o, e.Bounds.X + 3, e.Bounds.Y, e.Bounds.Width - 6, e.Bounds.Height);
                e.Graphics.DrawImage(Skin.explorer_detail_selection_r_o, e.Bounds.Right - 3, e.Bounds.Y, 3, e.Bounds.Height);
            }

            //Extrai informação do item
            TagMetadata metadata = (TagMetadata)e.Item.Tag;
            Image image = GetSmallIconFromMetadata(metadata);
            if (image != null) e.Graphics.DrawImage(image, e.Bounds.X + 4, e.Bounds.Y + 2, 16, 16);

            if (e.Item.Text != "")
            {
                StringFormat format = new StringFormat();
                format.Trimming = StringTrimming.EllipsisCharacter;
                format.LineAlignment = StringAlignment.Near;
                format.Alignment = StringAlignment.Near;

                RectangleF bounds = new RectangleF(e.Bounds.Left + textdraw_x,
                    e.Bounds.Top + (e.Bounds.Height - Skin.IconTitleFont.Height) / 2, e.Bounds.Width - textdraw_x,
                    Skin.IconTitleFont.Height);

                e.Graphics.DrawString(e.Item.Text, Skin.IconTitleFont, Brushes.Black, bounds,
                    format);
            }
        }

        private void DrawTileBackground(DrawListViewItemEventArgs e, bool mouseover)
        {
            if ((e.State & ListViewItemStates.Selected) != (ListViewItemStates)0)
            {
                if (Focused)
                {
                    e.Graphics.DrawImage(Skin.explorer_tile_selection_t_c, e.Bounds.X, e.Bounds.Y, e.Bounds.Width, 3);
                    e.Graphics.DrawImage(Skin.explorer_tile_selection_m_c, e.Bounds.X, e.Bounds.Y + 3, e.Bounds.Width, e.Bounds.Height - 6);
                    e.Graphics.DrawImage(Skin.explorer_tile_selection_b_c, e.Bounds.X, e.Bounds.Bottom - 3, e.Bounds.Width, 3);
                }
                else
                {
                    e.Graphics.DrawImage(Skin.explorer_tile_selection_t_oc, e.Bounds.X, e.Bounds.Y, e.Bounds.Width, 3);
                    e.Graphics.DrawImage(Skin.explorer_tile_selection_m_oc, e.Bounds.X, e.Bounds.Y + 3, e.Bounds.Width, e.Bounds.Height - 6);
                    e.Graphics.DrawImage(Skin.explorer_tile_selection_b_oc, e.Bounds.X, e.Bounds.Bottom - 3, e.Bounds.Width, 3);
                }
            }
            else if (mouseover)
            {
                e.Graphics.DrawImage(Skin.explorer_tile_selection_t_o, e.Bounds.X, e.Bounds.Y, e.Bounds.Width, 3);
                e.Graphics.DrawImage(Skin.explorer_tile_selection_m_o, e.Bounds.X, e.Bounds.Y + 3, e.Bounds.Width, e.Bounds.Height - 6);
                e.Graphics.DrawImage(Skin.explorer_tile_selection_b_o, e.Bounds.X, e.Bounds.Bottom - 3, e.Bounds.Width, 3);
            }
        }

        //------------------ Rotinas de determinação de ícone

        public static Image GetSmallIconFromMetadata(TagMetadata metadata)
        {
            switch (metadata.Type)
            {
                case SelectionType.Folder: return Skin.icon_16x16_folder;
                case SelectionType.File: return Skin.icon_16x16_file;
                case SelectionType.Rar: return Skin.icon_16x16_zip;
                case SelectionType.Iso: return Skin.icon_16x16_iso;
                case SelectionType.Disc: return Skin.icon_16x16_disc;
                case SelectionType.Drive:

                    IDrive drive = metadata.Meta1 as IDrive;
                    if (drive == null)
                    {
                        return Skin.icon_16x16_harddrive;
                    }
                    else
                    {
                        if (drive.Is(DriveFlags.WBFS))
                        {
                            return Skin.icon_16x16_wbfsdrive;
                        }
                        else if (drive.Is(DriveFlags.Removable))
                        {
                            if (drive.Name.StartsWith("A") || drive.Name.StartsWith("B"))
                            {
                                return Skin.icon_16x16_floppydrive;
                            }
                            else
                            {
                                return Skin.icon_16x16_usbdrive;
                            }
                        }
                        else if (drive.Is(DriveFlags.WinDrive))
                        {
                            return Skin.icon_16x16_windrive;
                        }
                        else if (drive.Is(DriveFlags.CDRom))
                        {
                            if (drive.Ready)
                            {
                                return Skin.icon_16x16_cddrive_full;
                            }
                            else
                            {
                                return Skin.icon_16x16_cddrive;
                            }
                        }
                        else
                        {
                            return Skin.icon_16x16_harddrive;
                        }
                    }

                default: return Skin.icon_16x16_file;
            }
        }

        public static Image GetSmallDriveIcon(IDrive drive)
        {
            if (drive == null)
            {
                return Skin.icon_16x16_harddrive;
            }
            else
            {
                if (drive.Is(DriveFlags.WBFS))
                {
                    return Skin.icon_16x16_wbfsdrive;
                }
                else if (drive.Is(DriveFlags.Removable))
                {
                    if (drive.Name.StartsWith("A") || drive.Name.StartsWith("B"))
                    {
                        return Skin.icon_16x16_floppydrive;
                    }
                    else
                    {
                        return Skin.icon_16x16_usbdrive;
                    }
                }
                else if (drive.Is(DriveFlags.WinDrive))
                {
                    return Skin.icon_16x16_windrive;
                }
                else if (drive.Is(DriveFlags.CDRom))
                {
                    if (drive.Ready)
                    {
                        return Skin.icon_16x16_cddrive_full;
                    }
                    else
                    {
                        return Skin.icon_16x16_cddrive;
                    }
                }
                else
                {
                    return Skin.icon_16x16_harddrive;
                }
            }
        }

        public static Image GetCoverIconFromMetadata(TagMetadata metadata, String code)
        {
            switch (metadata.Type)
            {
                case SelectionType.Folder: return Skin.icon_72x72_folder; 
                case SelectionType.File: return Skin.icon_72x72_file; 
                case SelectionType.Rar: return Skin.icon_72x72_zip; 
                case SelectionType.Iso: return Skin.icon_72x72_iso; 
                case SelectionType.Disc: return Covers.GetCover(code, true);
                default: return Skin.icon_72x72_file; 
            }
        }

        public static Image GetTileIconFromMetadata(TagMetadata metadata)
        {
            switch (metadata.Type)
            {
                case SelectionType.Folder: return Skin.icon_48x48_folder;
                case SelectionType.File: return Skin.icon_48x48_file;
                case SelectionType.Rar: return Skin.icon_48x48_zip;
                case SelectionType.Iso: return Skin.icon_48x48_iso;
                case SelectionType.Disc:
                    switch ((DiscRegion)metadata.Meta1)
                    {
                        case DiscRegion.NTSCJ: return Skin.icon_48x48_wiidisc_jap;
                        case DiscRegion.NTSCU: return Skin.icon_48x48_wiidisc_usa;
                        case DiscRegion.PAL: return Skin.icon_48x48_wiidisc_eur;
                        default: return Skin.icon_48x48_wiidisc_unk;
                    }
                   
                case SelectionType.Drive:

                    IDrive drive = metadata.Meta1 as IDrive;
                    if (drive == null)
                    {
                        return Skin.icon_48x48_harddrive;
                    }
                    else
                    {
                        if (drive.Is(DriveFlags.WBFS))
                        {
                            return Skin.icon_48x48_wbfsdrive;
                        }
                        else if (drive.Is(DriveFlags.Removable))
                        {
                            if (drive.Name.StartsWith("A"))
                            {
                                return Skin.icon_48x48_floppydrive;
                            }
                            else if (drive.Name.StartsWith("B"))
                            {
                                return Skin.icon_48x48_bigfloppydrive;
                            }
                            else
                            {
                                return Skin.icon_48x48_usbdrive;
                            }
                        }
                        else if (drive.Is(DriveFlags.WinDrive))
                        {
                            return Skin.icon_48x48_windrive;
                        }
                        else if (drive.Is(DriveFlags.CDRom))
                        {
                            if (drive.Ready)
                            {
                                return Skin.icon_48x48_cddrive_full;
                            }
                            else
                            {
                                return Skin.icon_48x48_cddrive;
                            }
                        }
                        else
                        {
                            return Skin.icon_48x48_harddrive;
                        }
                    }
                   

                default: return Skin.icon_48x48_file;
            }
        }

        //------------------ On's

        private void OnSuspendCoverModeChanged()
        {
            if (suspendCoverMode)
            {
                TileSize = tileSize_tilemode;
            }
            else if (ViewMode == ViewMode.Cover)
            {
                TileSize = tileSize_covermode;
            }
        }

        private void OnViewModeChanged()
        {
            if ((ViewMode == ViewMode.Tile) || forceFullSize)
            {
                View = View.Tile;
                if (!forceFullSize) TileSize = tileSize_tilemode;
            }
            else if (ViewMode == ViewMode.Cover)
            {
                View = View.Tile;
                if (!suspendCoverMode) TileSize = tileSize_covermode;
            }
            else if (ViewMode == ViewMode.Details)
            {
                View = View.Details;
            }
            else if (ViewMode == ViewMode.List)
            {
                View = View.List;
            }

            if (ViewModeChanged != null) ViewModeChanged(this, null);

        }

        private void OnForceFullSize()
        {
            if (forceFullSize)
            {
                View = View.Tile;
                TileSize = tileSize_fullsizemode;
                Covers.LoadFullSizeCovers();
            }
            else
            {
                OnViewModeChanged();
                Covers.DisposeFullSizeCovers();
            }
        }

        private void OnTileSizeChanged()
        {
        }
    }
}
